package photogcalc.calculators;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Screen;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.ChoiceGroup;
import javax.microedition.lcdui.TextField;
import javax.microedition.lcdui.Item;
import javax.microedition.lcdui.StringItem;

import java.util.Hashtable;
import java.util.Enumeration;
import java.util.Vector;

import net.sf.microlog.core.Logger;
import net.sf.microlog.core.LoggerFactory;

import photogcalc.common.Constants;
import photogcalc.common.DistanceSlider;
import photogcalc.common.FocalLengthSlider;
import photogcalc.i18n.I18n;
import photogcalc.i18n.I18nFactory;
import photogcalc.util.Settings;


/** J2ME application to helping with photographing related calculations
    @author Antti Okkonen
 */
public class AovView implements CommandListener {
    public static final String MENUNAME = "_Kuvakulmalaskin";
    public static final String ICONPREFIX = "aov";
    
    private ChoiceGroup cameraFormat;
    private ChoiceGroup focalLength;
    private FocalLengthSlider focalLengthSlider;
    private TextField distance;
    private DistanceSlider distanceSlider;
    private StringItem aovHoriz;
    private StringItem aovVert;
    private StringItem aovDiag;
    private StringItem size;
	
    private Command calculateCmd;
    private Command exitCmd;

    private I18n i18n = null;
    private DofCommandListener listener = null;
    private Settings settings = null;
    /** main screen */
    private Screen mainForm = null;
    
    private Logger logger = LoggerFactory.getLogger("AovView");

    /** Default constructor. */
    public AovView(Settings settings, DofCommandListener listener) {
        this.settings = settings;
        this.listener = listener;
        
        i18n = I18nFactory.createI18n(System.getProperty("microedition.locale"));

        mainForm = createUI();
    }

    public void initData(Hashtable CoCs, Vector flengths) {
        for (Enumeration keys = CoCs.keys(); keys.hasMoreElements();) {
            String tmp = (String) keys.nextElement();

            cameraFormat.append(tmp, null);
        }

        if (Constants.FLENGTH_SLIDER == false) {
            for (Enumeration flen = flengths.elements(); flen.hasMoreElements();) {
                Double val = (Double) flen.nextElement();
                focalLength.append(val.toString(), null);
            }
        }
    }

    public void commandAction(Command c, Displayable d) {
        // If any command is run, save input data to the datamodel.
        settings.put("cameraformat", cameraFormat.getString(cameraFormat.getSelectedIndex()));
        if (Constants.FLENGTH_SLIDER == false)
            settings.put("focallength", focalLength.getString(focalLength.getSelectedIndex()));
        else
            settings.put("focallength", Double.toString(focalLengthSlider.getValue()));
        if (Constants.DISTANCE_SLIDER == false)
            settings.put("distance", distance.getString().replace(',', '.'));
        else
            settings.put("distance", Double.toString(distanceSlider.getValue()));
        
        if (c == exitCmd) {
            listener.backCommand();
        } else if (c == calculateCmd) {
            listener.calculateCommand();
        }
        else {
            logger.warn("Unknown command " + c.getLabel());
        }
    }

    /** Creates and returns the main form
        @return the main form and it's menu
    */
    private Screen createUI() {
        Form form = new Form(i18n.get(MENUNAME));

        // Add commands to menu
        exitCmd = new Command(i18n.get("_Takaisin"), Command.BACK, 2);
        form.addCommand(exitCmd);

        calculateCmd = new Command(i18n.get("_Laske"), Command.OK, 1);
        form.addCommand(calculateCmd);

        form.setCommandListener(this);

        // Create UI items
        cameraFormat = new ChoiceGroup(
                i18n.get("_Kenno"),
                ChoiceGroup.POPUP);

        int fieldType = TextField.ANY;
        if (settings.get("textfielddefault").equals(new Integer(Constants.DECIMAL).toString())) {
            fieldType = TextField.DECIMAL;
        }

        if (Constants.FLENGTH_SLIDER == false) {
            focalLength = new ChoiceGroup(
                    i18n.get("_Polttovali"),
                    ChoiceGroup.POPUP);
        }
        else
            focalLengthSlider = new FocalLengthSlider(i18n.get("_Polttovali"));

        if (Constants.DISTANCE_SLIDER == false) {
            distance = new TextField(
                    i18n.get("_Etaisyys"),
                    Constants.DEFAULT_DISTANCE,
                    4,
                    fieldType);
        }
        else {
            distanceSlider = new DistanceSlider(i18n.get("_Etaisyys"));
        }

        aovHoriz = new StringItem(i18n.get("_Kuva-ala vaakasuunnassa"), "", Item.PLAIN);
        aovVert = new StringItem(i18n.get("_Kuva-ala pystysuunnassa"), "", Item.PLAIN);
        aovDiag = new StringItem(i18n.get("_Kuva-ala kulmasta kulmaan"), "", Item.PLAIN);
        size = new StringItem(i18n.get("_Kuva-alan koko"), "", Item.PLAIN);

        form.append(cameraFormat);
        if (Constants.FLENGTH_SLIDER == false)
            form.append(focalLength);
        else
            form.append(focalLengthSlider);
        if (Constants.DISTANCE_SLIDER == false)
            form.append(distance);
        else
            form.append(distanceSlider);
        form.append(aovHoriz);
        form.append(aovVert);
        form.append(aovDiag);
        form.append(size);

        return form;
    }

    public void setAovHoriz(String str) {
        aovHoriz.setText(str);
    }

    public void setAovVert(String str) {
        aovVert.setText(str);
    }

    public void setAovDiag(String str) {
        aovDiag.setText(str);
    }

    public void setSize(String str) {
        size.setText(str);
    }

    public void refresh() {
        String val;

        val = settings.get("cameraformat");
        if (val == null || val.length() == 0) {
            val = Constants.DEFAULT_CAMERAFORMAT;
        }
        setSelectedIndex(cameraFormat, val);

        val = settings.get("focallength");
        if (val == null || val.length() == 0) {
            val = Constants.DEFAULT_FOCALLENGTH;
        }
        if (Constants.FLENGTH_SLIDER == false)
            setSelectedIndex(focalLength, val);
        else
            focalLengthSlider.setValue(Double.parseDouble(val));

        val = settings.get("distance");
        if (val == null || val.length() == 0) {
            val = Constants.DEFAULT_DISTANCE;
        }
        if (Constants.DISTANCE_SLIDER == false)
            distance.setString(val);
        else
            distanceSlider.setValue(Double.parseDouble(val));
    }

    private void setSelectedIndex(ChoiceGroup group, String val) {
        try {
            int i = 0;
            boolean found = false;
            while (!found) {
                if (group.getString(i).equals(val)) {
                    group.setSelectedIndex(i, true);
                    found = true;
                }
                i++;
            }
        }
        catch (IndexOutOfBoundsException e) {
            // an aperture is not on the list
        }
    }

    public Screen getScreen() {
        return mainForm;
    }
}
